#pragma once
#include <sstream>
#include <fstream>
#include <boost/noncopyable.hpp>
#include <boost/filesystem/path.hpp>
#include "ImportExport.h"

namespace ja2{ namespace utils
{
	//! Log implementation.
	class Log : boost::noncopyable
	{
		// Enums
	public:
		//! Flush mode.
		enum FlushMode
		{
			FM_ON_DELETE,
			FM_BUFFER,
			FM_IMMEDIATELY,
		};

		// Attributes
	private:
		//! Path to log file.
		boost::filesystem::path m_FileName;
		//! Stream to write to.
		std::ofstream m_Stream;
		//! Flush mode.
		FlushMode m_FlushMode;
		//! Buffer size when flushing is needed.
		unsigned short const m_BufferFlushSize;
		//! Buffer used.
		std::ostringstream m_Buffer;
		bool					_first_write;
		//! log to cout.
		bool const m_LogToCout;

		// Operations
	public:
		//! Flush log.
		JA2_UTILS_API void flush(bool Force = true);
		//! Add new line.
		JA2_UTILS_API Log& endl();

		// Operators
	public:
		//! Add data.
		template<typename T>
		Log &operator<<(T const &Right);
		//! For wstring.
		JA2_UTILS_API Log &operator<<(std::string const &Right);
			
		// Construction/Destruction
	public:
		JA2_UTILS_API Log(boost::filesystem::path const &FileName, bool LogToCout = false, FlushMode FlushMode = FM_ON_DELETE);
		JA2_UTILS_API ~Log();
	};

	template<typename T>
	Log &Log::operator<<(T const &Right)
	{
		m_Buffer << Right;
		flush();

		return *this;
	}
} /*utils*/} /*ja2*/
